Pokémon data structure in Generation IV
Boxed Pokémon in the games are stored in a 136-byte structure. All unencrypted values are stored in little-endian format. The game encrypts the data when it is stored into save data. In-party Pokémon have additional values appended to them to hold calculated stats. The information below describes the boxed Pokémon data format. Checksum The checksum serves two purposes: # It validates the data after decryption, and # It serves as the encryption key for the data. The checksum is calculated in three steps: # Split the unencrypted data from offsets 0x08 to 0x87 into two-byte words, # Take the sum of the words, and # Truncate the sum to sixteen bits. Block shuffling The 128 bytes of Pokémon data are split into four 32-byte blocks for shuffling. The blocks are shuffled according to a shift value derived from the personality value. Given the personality value pv, the expression yielding the shift value is: : ((pv & 0x3E000) >> 0xD) % 24 The right shifting (>> 0xD) is equivalent to a division of 8192. To shuffle the blocks, take the four blocks of unencrypted data, A'', ''B, C'', and ''D. The blocks shall be rearranged in the encrypted data according to the Block Order column of the following table. (To unshuffle, use the Inverse column.) Encryption The encryption uses the pseudorandom number generator (PRNG), a linear congruential generator. Elements of the PRNG can be described with the recursive function: : Xn+1 = (0x41C64E6D * Xn + 0x6073) To decrypt the data, given a function rand() which returns the upper 16 bits of consecutive results of the above given function: # Seed the PRNG with the checksum (let Xn be the checksum). # Sequentially, for each 2-byte word Y'' from 0x08 to 0x87, apply the transformation: ''unencryptedByte = Y xor rand() # Unshuffle the blocks using the block shuffling algorithm above. To encrypt the data: # Shuffle the blocks using the block shuffling algorithm above. # Seed the PRNG with the checksum (let Xn be the checksum), # Sequentially, for each 2-byte word Y'' from 0x08 to 0x87, apply the transformation: ''unencryptedByte = Y xor rand() Unencrypted bytes Encrypted bytes Block A Block B Block C Block D Battle stats The battle stats are encrypted in the same manner, however the seed is not the checksum, it is the PID, and the bytes are not shuffled. Encrypted bytes Language of origin Markings Alternate forms Alternate forms are stored at offset 0x40 of the Pokémon structure. Each form follows the pattern of index << 3 where index starts at zero for the main form. Rotom's alternate forms, Giratina's Origin Forme, and Shaymin's Sky Forme will only be displayed in Pokémon Platinum. Rotom may be traded between Diamond, Pearl, and Platinum without losing the alternate form. Encounter types Ribbons DPPt stores the ribbon data as bitfields in 16-bit words. Given below are the bytewise representations of the ribbon bitfields: Sinnoh Ribbon Set 1 Sinnoh Ribbon Set 2 Hoenn Ribbon Set Location The party Pokémon are stored in the save file beginning at offset 0x00098 for the first block pair, and 0x40098 for the second block pair. Each party Pokémon is 236 bytes in size. The PC storage Pokémon are stored in the save file from Box 1 to Box 18. They start at 0x0C104 in the first block pair, and at 0x4C104 in the second block pair. Each PC stored Pokémon is 136 bytes in size.